extern int main();
extern void SystemInit();
extern void __libc_init_array();
/*
naked 属性 告诉编译器 不生成 压栈汇编 push {r7, lr}等指令

ARM 状态与 Thumb 状态
有些处理器同时支持 ARM 和 Thumb 指令集,通过 BX 或 BLX 指令进行切换,当指令 BX
跳转地址的 LSB 位为 1,表示切换到 Thumb 状态,为 0 则切换到 ARM 状态。

无论是 ARM 还是
Thumb,其指令在存储器中都是边界对齐的（2字节或4字节对齐）,也就是地址的最低位总是
0。 因此,在执行跳转过程中,PC 寄存器中的最低位被舍弃,不起作用。 在 BX
指令的执行过程中,最低位正好被用作状态判断的标志,不会造成存储器访问不对齐的错误。

Cortex-M 系列处理器不支持 ARM 指令,因此也不存在 ARM
状态,所以反汇编中的函数地址最低位都是 1

bin 部分数据含义
0x8000000-0x8000003  ：中断向量表定义 栈顶指针,SRAM最大地址  送  SP
0x8000004-0x8000008  : 存储 reset中断函数地址（_start_func） 送  PC
 */

// reset handle

__attribute__((naked)) void _start_func()
{
	extern unsigned int _sidata, _sdata, _edata, _sbss, _ebss;

	unsigned int *sdata;		// 0x20000000
	unsigned int *data_atflash; // 0x80000xx

	// copy data from flash to sram
	sdata = &_sdata;         // 0x20000000
	data_atflash = &_sidata; // 0x80000xx
	while (sdata < &_edata)
	{
		*sdata++ = *data_atflash++;
	}

	/*clear bss*/
	sdata = &_sbss;
	while (sdata < &_ebss)
	{
		*sdata++ = 0;
	}

	__libc_init_array();
	// SystemInit();
	main();
}

/***********************中断向量声明******************************* */
//  声明 中断函数 防止编译器报错
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif

__WEAK void NMI_Handler()
{
	for (;;)
	{
	}
}

__WEAK void HardFault_Handler()
{
	for (;;)
	{
	}
}

__WEAK void SVC_Handler() {}

__WEAK void PendSV_Handler() {}
__WEAK void SysTick_Handler() {}
__WEAK void WWDG_IRQHandler() {}	 /* reserved                     */
__WEAK void RTC_TAMP_IRQHandler() {} /* RTC through the EXTI line    */
__WEAK void FLASH_IRQHandler() {}	 /* FLASH                        */
__WEAK void RCC_IRQHandler() {}		 /* RCC                          */
__WEAK void EXTI0_1_IRQHandler() {}	 /* EXTI Line 0 and 1            */
__WEAK void EXTI2_3_IRQHandler() {}	 /* EXTI Line 2 and 3            */
__WEAK void EXTI4_15_IRQHandler() {} /* EXTI Line 4 to 15            */

__WEAK void DMA1_Channel1_IRQHandler() {}	/* DMA1 Channel 1               */
__WEAK void DMA1_Channel2_3_IRQHandler() {} /* DMA1 Channel 2 and Channel 3 */
__WEAK void DMA1_Ch4_5_DMAMUX1_OVR_IRQHandler()
{

} /* DMA1 Channel 4 to Channel 5, DMAMUX1 overrun */
__WEAK void ADC1_IRQHandler() {} /* ADC1                         */
__WEAK void TIM1_BRK_UP_TRG_COM_IRQHandler()
{

} /* TIM1 Break, Update, Trigger and Commutation */
__WEAK void TIM1_CC_IRQHandler() {} /* TIM1 Capture Compare         */

__WEAK void TIM3_IRQHandler() {} /* TIM3                         */

__WEAK void TIM14_IRQHandler() {} /* TIM14                        */

__WEAK void TIM16_IRQHandler() {}  /* TIM16                        */
__WEAK void TIM17_IRQHandler() {}  /* TIM17                        */
__WEAK void I2C1_IRQHandler() {}   /* I2C1                         */
__WEAK void I2C2_IRQHandler() {}   /* I2C2                         */
__WEAK void SPI1_IRQHandler() {}   /* SPI1                         */
__WEAK void SPI2_IRQHandler() {}   /* SPI2                         */
__WEAK void USART1_IRQHandler() {} /* USART1                       */
__WEAK void USART2_IRQHandler() {} /* USART2                       */

/*中断向量表 占用data 区*/
extern unsigned int _end_stack_bottom;
__attribute__((section(".vector"))) const void *__Vectors[] = {
	(void *)(&_end_stack_bottom), /*ram最大地址*/
	/*reset_handler 单片机复位后从这个地址开始运行 */
	/*cortex M只支持thumb2 指令,机器码最低位强制是1,所以地址会+1 */
	_start_func, NMI_Handler, HardFault_Handler, 0, 0, 0, 0, 0, 0, 0,
	SVC_Handler, 0, 0, PendSV_Handler, SysTick_Handler,
	WWDG_IRQHandler /* Window WatchDog              */
	,
	0 /* reserved                     */
	,
	RTC_TAMP_IRQHandler /* RTC through the EXTI line    */
	,
	FLASH_IRQHandler /* FLASH                        */
	,
	RCC_IRQHandler /* RCC                          */
	,
	EXTI0_1_IRQHandler /* EXTI Line 0 and 1            */
	,
	EXTI2_3_IRQHandler /* EXTI Line 2 and 3            */
	,
	EXTI4_15_IRQHandler /* EXTI Line 4 to 15            */
	,
	0 /* reserved                     */
	,
	DMA1_Channel1_IRQHandler /* DMA1 Channel 1               */
	,
	DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
	,
	DMA1_Ch4_5_DMAMUX1_OVR_IRQHandler /* DMA1 Channel 4 to Channel 5, DMAMUX1
										 overrun */
	,
	ADC1_IRQHandler /* ADC1                         */
	,
	TIM1_BRK_UP_TRG_COM_IRQHandler /* TIM1 Break, Update, Trigger and
									  Commutation */
	,
	TIM1_CC_IRQHandler /* TIM1 Capture Compare         */
	,
	0 /* reserved                     */
	,
	TIM3_IRQHandler /* TIM3                         */
	,
	0 /* reserved                     */
	,
	0 /* reserved                     */
	,
	TIM14_IRQHandler /* TIM14                        */
	,
	0 /* reserved                     */
	,
	TIM16_IRQHandler /* TIM16                        */
	,
	TIM17_IRQHandler /* TIM17                        */
	,
	I2C1_IRQHandler /* I2C1                         */
	,
	I2C2_IRQHandler /* I2C2                         */
	,
	SPI1_IRQHandler /* SPI1                         */
	,
	SPI2_IRQHandler /* SPI2                         */
	,
	USART1_IRQHandler /* USART1                       */
	,
	USART2_IRQHandler /* USART2                       */
	,
	0 /* reserved                     */
};
